package com.katesoft.scale4j.rttp.spring.postprocessor;

import com.katesoft.scale4j.log.Logger;
import com.katesoft.scale4j.log.LogFactory;
import com.katesoft.scale4j.rttp.client.IClusterInstanceAware;
import com.katesoft.scale4j.rttp.hibernate.SpringHazelcastBridge;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

/**
 * injects hazelcast instance for those beans, that implements {@link IClusterInstanceAware} interface.
 *
 * @author kate2007
 */
public class ClusterInstanceAwarePostProcessor implements BeanFactoryPostProcessor
{
    private Logger logger = LogFactory.getLogger(getClass());
    private SpringHazelcastBridge hazelcastBridge;

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException
    {
        String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
        for (String name : beanDefinitionNames) {
            Class<?> type = beanFactory.getType(name);
            if (IClusterInstanceAware.class.isAssignableFrom(type)) {
                BeanDefinition beanDefinition = beanFactory.getBeanDefinition(name);
                MutablePropertyValues mutablePropertyValues = beanDefinition.getPropertyValues();
                mutablePropertyValues.addPropertyValue("clusterInstance", hazelcastBridge.getHazelcastInstance());
                logger.info("injected cluster instance %s into %s bean using %s", hazelcastBridge.getHazelcastInstance(), name,
                            mutablePropertyValues.getPropertyValue("clusterInstance"));
            }
        }
    }

    @Required
    @Autowired
    public void setHazelcastBridge(SpringHazelcastBridge hazelcastBridge)
    {
        this.hazelcastBridge = hazelcastBridge;
    }
}
